package com.yex.service.impl;

import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.yex.base.WalletOper;
import com.yex.base.WalletOperEnum;
import com.yex.common.utils.DateUtils;
import com.yex.common.utils.PageUtils;
import com.yex.dao.OrderDao;
import com.yex.entity.*;
import com.yex.service.*;
import com.yex.utils.JsonResultVo;
import com.yex.utils.MathUtil;
import com.yex.utils.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private BankService bankService;
    @Autowired
    private LocaleMessageSourceService message;
    @Autowired
    private WalletService walletService;
    @Autowired
    private OrderBankService orderBankService;
    @Autowired
    private BankListService bankListService;

    @Override
    public PageUtils queryPage(Map<String, Object> params, String filter) {
        Page<Map<String, Object>> page = new Query<Map<String, Object>>(params).getPage();
        List<Map<String, Object>> orderEntityList = baseMapper.selectPageFilter(page, filter);
        for (Map<String, Object> map : orderEntityList) {
            BigDecimal price = (BigDecimal) map.get("price");
            BigDecimal number = (BigDecimal) map.get("number");
            Date createTime = (Date) map.get("create_time");
            map.put("amount", MathUtil.getBigDecimalString(MathUtil.mul(price, number), 2));
            map.put("createTime", DateUtils.format(createTime, DateUtils.DATE_TIME_PATTERN));
        }
        page.setRecords(orderEntityList);
        return new PageUtils(page);
    }

    @Override
    @Transactional
    public JsonResultVo insertOrder(OrderEntity orderEntity) {
        /*List<OrderEntity> orderEntityList = baseMapper.selectOrderNoPayByUserId(orderEntity.getUserId());
        if (orderEntityList.size() > 0) {
            return new JsonResultVo(message.getMessage("fail"), -1);
        }*/

        Map<String, Object> mapParams = new HashMap<>(2);
        mapParams.put("status", "1");
        List<OrderBankEntity> orderBankEntitieList = orderBankService.selectByMap(mapParams);
        if (orderBankEntitieList.size() <= 0) {
            return new JsonResultVo(message.getMessage("fail"), -1);
        }

        if (orderEntity.getType() == 1) {
            List<BankEntity> bankEntityList = bankService.selectBankListByUserId(orderEntity.getUserId());
            if (bankEntityList.size() <= 0) {
                return new JsonResultVo(message.getMessage("fail"), -1);
            }
            orderEntity.setStatus(1);
        }

        OrderBankEntity orderBankEntity = orderBankEntitieList.get(0);
        orderEntity.setCardNumber(orderBankEntity.getCardNumber());
        orderEntity.setName(orderBankEntity.getName());
        orderEntity.setBranchAddress(orderBankEntity.getBranchAddress());
        orderEntity.setAddress(orderBankEntity.getAddress());
        orderEntity.setBank(orderBankEntity.getBank());
        orderEntity.setBankRemarks(DateUtils.format(new Date(), "yyyyMMddHHmmss"));

        Integer result = baseMapper.insert(orderEntity);
        if(result<=0){
            return   new JsonResultVo(message.getMessage("fail"), -1);
        }
        if (orderEntity.getType() == 1) {
            WalletEntity walletEntity = walletService.selectByUserId(orderEntity.getUserId());
            if (walletEntity == null) {
                return new JsonResultVo(message.getMessage("fail"), -1);
            }
            WalletOper walletOper = new WalletOper();
            walletOper.setUserId(orderEntity.getUserId());
            walletOper.setAmount(orderEntity.getNumber());
            walletOper.setRemark("冻结卖出数量");
            walletOper.setOper(WalletOperEnum.FROZEN);
            walletOper.setId(walletEntity.getId());
            walletService.updateWallet(walletOper);
        }

        Map<String, Object> map = new HashMap<>(2);
        map.put("id", orderEntity.getId());

        return new JsonResultVo(message.getMessage("success"), map, 0);
    }

    @Override
    @Transactional
    public JsonResultVo updatePayOrder(String orderId) {
        OrderEntity orderEntity = baseMapper.selectById(orderId);
        if (orderEntity == null) {
            return new JsonResultVo(message.getMessage("fail"), -1);
        }
        Integer result = baseMapper.updatePayOrder(orderEntity.getId());
        return result > 0 ? new JsonResultVo(message.getMessage("success")) : new JsonResultVo(message.getMessage("fail"), -1);
    }


    @Override
    @Transactional
    public JsonResultVo updateOrderAuditing(Integer id) {
        Integer result = baseMapper.updateOrderAuditing(id);
        if (result <= 0) {
            return new JsonResultVo(message.getMessage("fail"), -1);
        }

        OrderEntity orderEntity = baseMapper.selectById(id);
        WalletEntity walletEntity = walletService.selectByUserId(orderEntity.getUserId());
        WalletOper walletOper = new WalletOper();

        if (orderEntity.getType() == 0) {
            walletOper.setUserId(orderEntity.getUserId());
            walletOper.setAmount(orderEntity.getNumber());
            walletOper.setRemark("买入数量");
            walletOper.setOper(WalletOperEnum.ADD);
            if (walletEntity != null) {
                walletOper.setId(walletEntity.getId());
            }
            return walletService.updateWallet(walletOper);
        } else {
            if (walletEntity == null) {
                return new JsonResultVo(message.getMessage("fail"), -1);
            }
            walletOper.setUserId(orderEntity.getUserId());
            walletOper.setAmount(orderEntity.getNumber());
            walletOper.setRemark("扣减卖出冻结数量");
            walletOper.setOper(WalletOperEnum.REDUCE_FROZEN);
            walletOper.setId(walletEntity.getId());
            return walletService.updateWallet(walletOper);
        }

    }

    @Override
    @Transactional
    public JsonResultVo updateOrderNoAuditing(Integer id) {

        Integer result = baseMapper.updateOrderNoAuditing(id);
        if (result <= 0) {
            return new JsonResultVo(message.getMessage("fail"), -1);
        }

        OrderEntity orderEntity = baseMapper.selectById(id);
        WalletEntity walletEntity = walletService.selectByUserId(orderEntity.getUserId());
        WalletOper walletOper = new WalletOper();

        if (orderEntity.getType() == 0) {
            return new JsonResultVo(message.getMessage("success"));
        } else {
            if (walletEntity == null) {
                return new JsonResultVo(message.getMessage("fail"), -1);
            }
            walletOper.setUserId(orderEntity.getUserId());
            walletOper.setAmount(orderEntity.getNumber());
            walletOper.setRemark("解冻卖出冻结数量");
            walletOper.setOper(WalletOperEnum.UNFRONZEN);
            walletOper.setId(walletEntity.getId());
            return walletService.updateWallet(walletOper);
        }
    }

    @Override
    @Transactional
    public JsonResultVo updateRevokeOrder(String orderId) {
        Integer result = baseMapper.updateOrderRevoke(Integer.valueOf(orderId));
        return result > 0 ? new JsonResultVo(message.getMessage("success")) : new JsonResultVo(message.getMessage("fail"), -1);
    }


    @Override
    public JsonResultVo selectOrderInfo(Integer userId, String orderId) {
        OrderEntity orderEntity = baseMapper.selectById(orderId);
        if (orderEntity == null) {
            return new JsonResultVo(message.getMessage("fail"), -1);
        }
        Map<String, Object> map = new HashMap<>(10);
        map.put("id", orderEntity.getId());
        map.put("type", orderEntity.getType());
        map.put("price", orderEntity.getPrice());
        map.put("number", orderEntity.getNumber());
        map.put("status", orderEntity.getStatus());
        map.put("createTime", DateUtils.format(orderEntity.getCreateTime(), DateUtils.DATE_TIME_PATTERN));
        long time = System.currentTimeMillis() - orderEntity.getCreateTime().getTime();
        if (time <= 0) {
            map.put("expire_time", 0);
        } else {
            map.put("expire_time", time);
        }
        map.put("amount", MathUtil.getBigDecimalString(MathUtil.mul(orderEntity.getPrice(), orderEntity.getNumber()), 2));
        BankListEntity bankListEntity = bankListService.selectById(orderEntity.getBank());
        map.put("bankName", orderEntity.getName());
        map.put("bankCardNumber", orderEntity.getCardNumber());
        map.put("bankAddress", bankListEntity.getTitle() + orderEntity.getBranchAddress());
        map.put("bankRemarks", orderEntity.getBankRemarks());
        return new JsonResultVo(message.getMessage("success"), map, 0);
    }

    @Override
    @Transactional
    public JsonResultVo updateOrderOvertime() {
        Map<String, Object> mapParams = new HashMap<>(2);
        mapParams.put("status", "0");
        List<OrderEntity> orderEntitielList = baseMapper.selectByMap(mapParams);
        for (OrderEntity orderEntity : orderEntitielList) {
            long start = System.currentTimeMillis();
            long end = orderEntity.getCreateTime().getTime();
            long params = 30 * 60 * 1000;
            if ((start - end) >= params) {
                Integer result = baseMapper.updateOrderOvertime(orderEntity.getId());
                if (result <= 0) {
                    logger.info("订单超时执行错误，id：" + orderEntity.getId());
                }
            }
        }
        return new JsonResultVo(message.getMessage("success"));
    }
}

